package com.hmdp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hmdp.dto.Result;
import com.hmdp.dto.ScrollResult;
import com.hmdp.dto.UserDTO;
import com.hmdp.entity.Blog;
import com.hmdp.entity.Follow;
import com.hmdp.mapper.FollowMapper;
import com.hmdp.service.IFollowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmdp.service.IUserService;
import com.hmdp.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.print.attribute.IntegerSyntax;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.FEED_KEY;
import static com.hmdp.utils.RedisConstants.FOLLOW_KEY;


@Slf4j
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IUserService userService;

    private static final long CACHE_TIMEOUT_HOURS = 24;

    //判断是否关注
    @Override
    public Result isFollow(Long followedId) {
        if (followedId == null) {
            return Result.fail("关注用户ID不能为空");
        }
        try {
            Long userId = UserHolder.getUser().getId();
            Integer count = lambdaQuery()
                    .eq(Follow::getFollowUserId, followedId)
                    .eq(Follow::getUserId, userId)
                    .count();
            return Result.ok(count > 0);
        } catch (Exception e) {
            log.error("查询关注状态失败", e);
            return Result.fail("查询关注状态失败");
        }
    }

    //关注or取关
    @Override
    public Result follow(Long followedId, Boolean isFollowed) {
        if (followedId == null) {
            return Result.fail("关注用户ID不能为空");
        }
        
        try {
            Long userId = UserHolder.getUser().getId();
            String key = FOLLOW_KEY + userId;
            
            if (isFollowed) {
                return handleFollow(userId, followedId, key);
            } else {
                return handleUnfollow(userId, followedId, key);
            }
        } catch (Exception e) {
            log.error("处理关注操作失败", e);
            return Result.fail("操作失败，请稍后重试");
        }
    }

    private Result handleFollow(Long userId, Long followedId, String key) {
        // 避免自己关注自己
        if (userId.equals(followedId)) {
            return Result.fail("不能关注自己");
        }
        
        boolean result = this.save(new Follow()
                .setUserId(userId)
                .setFollowUserId(followedId));
                
        if (result) {
            stringRedisTemplate.opsForSet().add(key, followedId.toString());
            // 设置过期时间
            stringRedisTemplate.expire(key, CACHE_TIMEOUT_HOURS, TimeUnit.HOURS);
        }
        return Result.ok();
    }

    private Result handleUnfollow(Long userId, Long followedId, String key) {
        boolean result = this.remove(new LambdaQueryWrapper<Follow>()
                .eq(Follow::getUserId, userId)
                .eq(Follow::getFollowUserId, followedId));
                
        if (result) {
            stringRedisTemplate.opsForSet().remove(key, followedId.toString());
        }
        return Result.ok();
    }

    //查看共同关注
    @Override
    public Result showCommonUsers(Long id) {
        if (id == null) {
            return Result.fail("用户ID不能为空");
        }
        
        try {
            Long userId = UserHolder.getUser().getId();
            String key = FOLLOW_KEY;
            
            // 使用Redis计算交集
            Set<String> intersect = stringRedisTemplate.opsForSet()
                    .intersect(key + id, key + userId);
                    
            if (CollUtil.isEmpty(intersect)) {
                return Result.ok(Collections.emptySet());
            }
            
            // 优化：一次性查询所有用户信息
            List<Long> userIds = intersect.stream()
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
                    
            List<UserDTO> commonUsers = userService.listByIds(userIds)
                    .stream()
                    .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                    .collect(Collectors.toList());
                    
            return Result.ok(commonUsers);
        } catch (Exception e) {
            log.error("查询共同关注失败", e);
            return Result.fail("查询共同关注失败");
        }
    }

}
